home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / x2ftp / msdos / source / demostu2 / shade1.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1994-12-13  |  8.4 KB  |  494 lines

  1. program Read1;
  2. {
  3.   Vector shade
  4.   - by Bjarke Viksφe
  5.   aug 1994
  6.  
  7.   Works pretty much the same as gouraud vectors.
  8.   Instead of using z-coord as colour, we use a fixed colour value
  9.   to shade to.
  10. }
  11.  
  12. {$DEFINE DEBUG}
  13.  
  14. uses
  15.     DEMOINIT;
  16.  
  17. const
  18.     NUMBER_FACES = 6;
  19.     NUMBER_COORDS = 8;
  20.     box = 120; {size of box}
  21.  
  22. type
  23.     SlopeType = array[0..200*2] of integer;
  24.  
  25.     FaceType = RECORD
  26.         l1,l2,l3,l4 : byte;
  27.     end;
  28.  
  29.  
  30. var
  31.     slope,zslope : SlopeType;
  32.     face : array[1..NUMBER_FACES] of FaceType;
  33.     cbuffer : array[0..NUMBER_COORDS*4-1] of integer;
  34.  
  35.     LineTable1 : array[0..319] of byte;
  36.     LineTable2 : array[0..319] of byte;
  37.  
  38.     miny,maxy, scrminy,scrmaxy : integer;
  39.     lastscrminy,lastscrmaxy : integer;
  40.  
  41.     sinustabel : array[0..639] of integer;
  42.     v1,v2,v3 : word;
  43.     cos1,sin1,cos2,sin2,cos3,sin3 : integer;
  44.  
  45.     xkoord,ykoord,zkoord, n : integer;
  46.  
  47. const
  48.     {setup coords for a box}
  49.     coords : array[0..NUMBER_COORDS*3-1] of integer =
  50.         (box,box,-box, -box,box,-box, -box,-box,-box, box,-box,-box,
  51.         box,box,box, -box,box,box, -box,-box,box, box,-box,box);
  52.  
  53. const
  54.     display1 : word = $0000;
  55.     display2 : word = $4000;
  56.  
  57.  
  58. (*------------------------------------------------*)
  59.  
  60. procedure SetupSinus;
  61. var
  62.     i : integer;
  63.     v, vadd : real;
  64. begin
  65.     v:=0.0;
  66.     vadd:=(2.0*pi/512.0);
  67.     for i:=0 to 639 do begin
  68.         sinustabel[i]:=round(sin(v)*32767);
  69.         v:=v+vadd;
  70.     end;
  71. end;
  72.  
  73. procedure SetupFaces;
  74. {setup faces. Make sure face keeps track of which coordinates it uses!}
  75. begin
  76.     with face[1] do begin l1:=3; l2:=2; l3:=1; l4:=0; end;
  77.     with face[2] do begin l1:=4; l2:=5; l3:=6; l4:=7; end;
  78.     with face[3] do begin l1:=0; l2:=1; l3:=5; l4:=4; end;
  79.     with face[4] do begin l1:=1; l2:=2; l3:=6; l4:=5; end;
  80.     with face[5] do begin l1:=2; l2:=3; l3:=7; l4:=6; end;
  81.     with face[6] do begin l1:=3; l2:=0; l3:=4; l4:=7; end;
  82. end;
  83.  
  84. procedure InitDemo;
  85. var
  86.     i : integer;
  87. begin
  88.     Screen_Off;
  89.     ClearWholeScreen;
  90.     SetupSinus;
  91.     SetupFaces;
  92.  
  93.     scrminy := 0; scrmaxy := 200;
  94.     lastscrminy := 0; lastscrmaxy := 200;
  95.     v1:=0; v2:=0; v3:=0;
  96.  
  97.     for i:=1 to 63 do SetRGB(i,0,64-i,40);
  98.     for i:=64 to 127 do SetRGB(i,0,0,0);
  99.  
  100.     for i:=0 to 319 do begin
  101.         LineTable1[i]:=(15 SHL (i AND 3)) AND 15;
  102.         LineTable2[i]:=(2 SHL (i AND 3))-1;
  103.     end;
  104.  
  105.     Screen_On;
  106. end;
  107.  
  108.  
  109. (*------------------------------------------------*)
  110.  
  111. procedure SwapDisplay;
  112. var
  113.     temp : word;
  114. begin
  115.     temp:=display2;
  116.     display2:=display1;
  117.     display1:=temp;
  118.     SetAddress(Ptr(SEGA000,display2));
  119. end;
  120.  
  121. procedure ClearScreen(y1,y2 : integer); assembler;
  122. asm
  123.     mov    dx,$3C4
  124.     mov    ax,$0F02
  125.     out    dx,ax
  126.  
  127.     mov    bx,y1        {clear box around vector - only y-coords are actually}
  128.     mov    dx,y2        {used for calculation... x-coords are constant 192 pixels}
  129.     sub    dx,bx
  130.     cmp    dx,200
  131.     ja        @done
  132.  
  133.     lea    si,ytabel
  134.     add    bx,bx
  135.     mov    di,[si+bx]
  136.     add    di,display1
  137.     add    di,16
  138.  
  139.     mov    es,SEGA000
  140.     xor ax,ax
  141.     mov    bx,48/2
  142. @loop:
  143.     mov    cx,bx
  144.     rep stosw
  145.     add    di,WIDTH-48
  146.     dec    dl
  147.     jnz    @loop
  148. @done:
  149. end;
  150.  
  151.  
  152. (*------------------------------------------------*)
  153.  
  154. procedure ClearSlope; assembler;
  155. asm
  156.     mov    ax,ds
  157.     mov    es,ax
  158.     lea    di,slope
  159.     DB LONG; mov ax,$8000; DW $8000;
  160.     cld
  161.     mov    cx,TYPE(slopetype)/4
  162.     rep; DB LONG; stosw
  163. end;
  164.  
  165. procedure CalcSlope(l1,l2 : integer; col1a,col1b : word); assembler;
  166. var
  167.     col1add : word;
  168.     xlowadd : word;
  169.     ysize : integer;
  170. asm
  171.     lea    si,cbuffer
  172.     DB LONG; xor cx,cx
  173.     mov    bx,l1                    {get first coords}
  174.     shl    bx,3
  175.     mov    dx,[si+bx]            {get x/y coords}
  176.     mov    cx,[si+bx+2]
  177.  
  178.     mov    ax,l2                    {get second coords}
  179.     shl    ax,3
  180.     add    si,ax
  181.     mov    ax,[si]                {get x/y coords}
  182.     mov    bx,[si+2]
  183.  
  184.     cmp    bx,cx                    {make sure we go downwards...}
  185.     jle    @noswap
  186.     mov    si,col1a                {swap colour}
  187.     xchg    col1b,si
  188.     mov    col1a,si
  189.     xchg    ax,dx                    {swap x}
  190.     xchg    bx,cx                    {sway y}
  191. @noswap:
  192.  
  193.     cmp    bx,miny                {record miny and maxy}
  194.     jae    @miny
  195.     mov    miny,bx
  196. @miny:
  197.     cmp    cx,maxy
  198.     jbe    @maxy
  199.     mov    maxy,cx
  200. @maxy:
  201.  
  202.     sub    cx,bx
  203.     jcxz    @zero
  204.     mov    ysize,cx
  205.     add    bx,bx
  206.     add    bx,bx
  207.     lea    si,slope
  208.     add    si,bx
  209.  
  210.     push    ax
  211.     sub    dx,ax
  212.  
  213.     mov    ax,dx
  214.     DB LONG; shl    ax,16
  215.     {cdq} DB $66,$99
  216.     DB LONG; idiv    cx
  217.     DB LONG; mov    dx,ax
  218.     DB LONG; shr    dx,16
  219.     mov    xlowadd,ax
  220.  
  221.     push    dx
  222.     mov    dh,BYTE PTR col1a
  223.     mov    ah,BYTE PTR col1b
  224.     sub    ah,dh
  225.     xor    al,al
  226.     cwd
  227.     idiv    cx
  228.     mov    col1add,ax
  229.     pop    dx
  230. @one:
  231.     pop    cx
  232.  
  233.     xor    bx,bx
  234.     mov    ah,BYTE PTR col1a    {prepare also colour-slope calc}
  235.     xor    al,al
  236.     mov    di,$8000
  237. @loop:
  238.     cmp    [si],di
  239.     jne    @other
  240.     mov    [si+TYPE(SlopeType)],ah
  241.     mov    [si],cx
  242.     add    si,4
  243.     add    bx,xlowadd
  244.     adc    cx,dx
  245.     add    ax,col1add
  246.     dec    ysize
  247.     jnz    @loop
  248.     jmp    NEAR PTR @zero
  249. @other:
  250.     mov    [si+TYPE(SlopeType)+2],ah
  251.     mov    [si+2],cx
  252.     add    si,4
  253.     add    bx,xlowadd
  254.     adc    cx,dx
  255.     add    ax,col1add
  256.     dec    ysize
  257.     jnz    @loop
  258. @zero:
  259. end;
  260.  
  261.  
  262. (*------------------------------------------------*)
  263.  
  264. procedure CalcAngle;
  265. begin
  266.     sin1:=sinustabel[v1]; cos1:=sinustabel[v1+128];
  267.     sin2:=sinustabel[v2]; cos2:=sinustabel[v2+128];
  268.     sin3:=sinustabel[v3]; cos3:=sinustabel[v3+128];
  269.     v1:=(v1-1) AND 511;
  270.     v2:=(v2+1) AND 511;
  271.     v3:=(v3+2) AND 511;
  272. end;
  273.  
  274. procedure RotateAllCoords;
  275. var
  276.     i, a,b : integer;
  277.     x,y,z : longint;
  278.     temp : integer;
  279. begin
  280.     a:=0; b:=0;
  281.     for i:=1 to NUMBER_COORDS do begin
  282.         x:=coords[a]; y:=coords[a+1]; z:=coords[a+2];
  283.         inc(a,3);
  284.  
  285.         temp:=y;
  286.         y:=(LongMul(y,cos1) - LongMul(z,sin1)) DIV 32768;
  287.         z:=(LongMul(temp,sin1) + LongMul(z,cos1)) DIV 32768;
  288.         temp:=x;
  289.         x:=(LongMul(x,cos2) + LongMul(z,sin2)) DIV 32768;
  290.         z:=(LongMul(z,cos2) - LongMul(temp,sin2)) DIV 32768;
  291.         temp:=x;
  292.         x:=(LongMul(x,cos3) - LongMul(y,sin3)) DIV 32768;
  293.         y:=(LongMul(temp,sin3) + LongMul(y,cos3)) DIV 32768;
  294.  
  295.         cbuffer[b]:=((x SHL 8) DIV (z+800))+160;
  296.         cbuffer[b+1]:=((y SHL 8) DIV (z+800))+100;
  297.         cbuffer[b+2]:=(z-390);
  298.         inc(b,4);
  299.     end;
  300. end;
  301.  
  302.  
  303. function FaceShown(i : integer; l1,l2,l3 : byte) : boolean;
  304. var
  305.     a,b : longint;
  306. begin
  307.     a := longmul(cbuffer[l1]-cbuffer[l2],cbuffer[l3+1]-cbuffer[l2+1]);
  308.     b := longmul(cbuffer[l1+1]-cbuffer[l2+1],cbuffer[l3]-cbuffer[l2]);
  309.     FaceShown := (a-b) > 0;
  310. end;
  311.  
  312.  
  313. procedure FillShape(y,ysize : integer); assembler;
  314. var
  315.     c1,c2 : byte;
  316. asm
  317.     cmp    ysize,200
  318.     jae    @done
  319.     mov    ax,y
  320.     add    ax,ax
  321.     mov    si,ax
  322.     mov    di,[si+OFFSET ytabel]
  323.     add    di,display1
  324.     lea    si,slope
  325.     add    ax,ax
  326.     add    si,ax
  327.  
  328.     mov    es,SEGA000
  329.     mov    dx,$3C4
  330.     mov    al,$02
  331.     out    dx,al
  332.     cld
  333. @yloop:
  334.     mov    bh,[si+TYPE(slopetype)] {fetch z value}
  335.     lodsw                                    {fetch first xpos}
  336.     mov    dx,ax
  337.     mov    bl,[si+TYPE(slopetype)] {fetch second z value}
  338.     lodsw                                    {fetch second xpos}
  339.     cmp    ax,dx
  340.     jle    @exchange
  341.     xchg    ax,dx
  342.     xchg    bl,bh
  343. @exchange:
  344.     mov    c1,bl
  345.     mov    c2,bh
  346.  
  347.     cmp    dx,0
  348.     jl        @filledout_fast
  349.     cmp    ax,320
  350.     jge    @filledout_fast
  351.     cmp    ax,0
  352.     jge    @cut1
  353.     xor    ax,ax
  354. @cut1:
  355.     cmp    dx,319
  356.     jle    @cut2
  357.     mov    dx,319
  358. @cut2:
  359.     push    si
  360.     push    di
  361.     mov    bx,ax
  362.     mov    si,dx
  363.     mov    dx,$3C5
  364.  
  365. {the next lines are ripped from THE FAKER/S!P shade example}
  366.     mov    al,[bx+OFFSET LineTable1]
  367.     mov    ah,[si+OFFSET LineTable2]
  368.     shr    bx,2
  369.     shr    si,2
  370.     mov    cx,si
  371.     sub    cx,bx
  372.     jcxz    @1
  373.     dec    cx
  374.     add    di,bx
  375.     mov    bh,ah
  376.     out    dx,al
  377.     mov    al,c1
  378.     shr    al,1
  379.     stosb
  380.     jcxz    @4
  381.     mov    al,0Fh
  382.     out    dx,al
  383.     push    bx
  384.     xor    dx,dx
  385.     xor    al,al
  386.     mov    ah,c2
  387.     sub    ah,c1
  388.     sbb    dx,0
  389.     idiv    cx
  390.     mov    si,ax
  391.  
  392.     mov    dh,c1
  393.     mov    dl,0
  394.     shr    cx,1
  395.     jnc    @2
  396.     add    dx,si
  397.     mov    ax,dx
  398.     shr    ax,9
  399.     stosb
  400.     jcxz    @5
  401.  
  402. @2:
  403.     add    dx,si
  404.     mov    bx,dx
  405.     shr    bx,1
  406.     add    dx,si
  407.     mov    ax,dx
  408.     shr    ax,1
  409.     mov    al,bh
  410.     stosw
  411.     loop    @2
  412.  
  413. @5: pop    bx
  414.  
  415. @4:
  416.     mov al,bh
  417.     mov dx,3c5h
  418.     out dx,al
  419.     mov al,c2
  420.     shr al,1
  421.     stosb
  422.     jmp @3
  423.  
  424. @1:
  425.     add    di,bx
  426.     and    al,ah
  427.     out    dx,al
  428.     mov    al,c1
  429.     add    al,c2
  430.     rcr    al,1
  431.     shr    al,1
  432.     stosb
  433.  
  434. @3:
  435.  
  436. @filledout:
  437.     pop    di
  438.     pop    si
  439. @filledout_fast:
  440.     add    di,WIDTH
  441.     dec    ysize
  442.     jnz    @yloop
  443. @done:
  444. end;
  445.  
  446.  
  447. procedure RunOnce;
  448. var
  449.     i : integer;
  450. begin
  451.     SwapDisplay;
  452.     VBLANK;
  453. {$IFDEF DEBUG}
  454.     SetRGB(0,20,0,0);
  455. {$ENDIF}
  456.  
  457.     ClearScreen(lastscrminy,lastscrmaxy);
  458.  
  459.     lastscrminy := scrminy; lastscrmaxy := scrmaxy;
  460.     scrminy := 200; scrmaxy := 0;
  461.  
  462.     CalcAngle;
  463.     RotateAllCoords;
  464.  
  465.     for i:=1 to NUMBER_FACES do begin
  466.         with face[i] do if FaceShown(i, l1 SHL 2,l2 SHL 2,l3 SHL 2) then begin
  467.             ClearSlope;
  468.             miny := 200; maxy := 0;
  469.             CalcSlope(l1,l2, 2,2);
  470.             CalcSlope(l2,l3, 125,2);
  471.             CalcSlope(l3,l4, 125,125);
  472.             CalcSlope(l4,l1, 2,125);
  473.             FillShape(miny, maxy-miny);
  474.             if (miny < scrminy) then scrminy := miny;
  475.             if (maxy > scrmaxy) then scrmaxy := maxy;
  476.         end;
  477.     end;
  478.  
  479. {$IFDEF DEBUG}
  480.     SetRGB(0,0,0,0);
  481.     while KeyHit[26] do ; {Hit 'P' to pause}
  482. {$ENDIF}
  483. end;
  484.  
  485.  
  486. begin
  487.     OpenScreen;
  488.     InitDemo;
  489.     SetAllInterrupts;
  490.     repeat RunOnce until Key='e';
  491.     RestoreAllInterrupts;
  492.     CloseScreen;
  493. end.
  494.